#ifdef UTIL_PLATFORM_LINUX
#include "io/File.h"
#include "dirent.h"
#include "sys/stat.h"
#include "unistd.h"
using namespace yzrilyzr_lang;
namespace yzrilyzr_io{
	String File::getAbsolutePath() const{
		// �洢����·���Ļ�������ʹ��PATH_MAXȷ���㹻����
		char absolutePath[PATH_MAX]={0};

		// ����realpath�������·���ͷ�������
		if(realpath(path.c_str(), absolutePath) == nullptr){
			// ��·�������ڣ�������getcwdƴ�ӵ�ǰĿ¼
			char currentDir[PATH_MAX]={0};
			if(getcwd(currentDir, PATH_MAX) == nullptr){
				return ""; // �޷���ȡ��ǰĿ¼�����ؿ�
			}
			// ƴ�ӵ�ǰĿ¼�����·��
			std::string combined=std::string(currentDir) + "/" + path.tostring();
			if(realpath(combined.c_str(), absolutePath) != nullptr){
				return absolutePath;
			}
			return ""; // ����ʧ�ܷ��ؿ�
		}

		return absolutePath;
	}
	std::vector<String> File::list()const{
		std::vector<String> fileList;
		DIR * dir=opendir(path.c_str());
		if(dir){
			struct dirent * entry;
			while((entry=readdir(dir)) != nullptr){
				const std::string fileOrDir=entry->d_name;
				if(fileOrDir != "." && fileOrDir != ".."){
					// ƴ������·����path + "/" + �ļ�����
					fileList.push_back(path + "/" + fileOrDir);
				}
			}
			closedir(dir);
		} else{
			std::cerr << "Error opening directory: " << path << " (Error: " << strerror(errno) << ")" << std::endl;
		}
		return fileList;
	}
	uint64_t File::length() const{
		struct stat statbuf;
		// ��� stat �Ƿ�ɹ�
		if(stat(path.c_str(), &statbuf) != 0){
			// ��ѡ���׳��쳣���� Windows һ�£��򷵻� 0
			std::cerr << "Error getting file length: " << path << " (Error: " << strerror(errno) << ")" << std::endl;
			return 0;
		}
		// �޸���st_size �� off_t������Ϊ 64 λ����ת��Ϊ u_index
		return static_cast<u_index>(statbuf.st_size);
	}
	bool File::exists() const{
		struct stat info;
		return (stat(path.c_str(), &info) == 0);
	}
	bool File::isFile() const{
		struct stat info;
		if(stat(path.c_str(), &info) != 0) return false;
		return S_ISREG(info.st_mode); // ����Ƿ�Ϊ��ͨ�ļ�
	}
	bool File::isDirectory() const{
		struct stat info;
		if(stat(path.c_str(), &info) != 0) return false;
		return S_ISDIR(info.st_mode); // ����Ƿ�ΪĿ¼
	}
	bool File::deleteFile() const{
		if(!exists()) return false;
		if(isFile()) return unlink(path.c_str()) == 0;
		if(isDirectory()){
			bool isEmpty=false;
			DIR * dir=opendir(path.c_str());
			if(!dir) return false;
			isEmpty=true;
			struct dirent * entry;
			while((entry=readdir(dir)) != nullptr){
				std::string name=entry->d_name;
				if(name != "." && name != ".."){
					isEmpty=false;
					break;
				}
			}
			closedir(dir);
			return isEmpty?(rmdir(path.c_str()) == 0):false;
		}
		return false;
	}
	bool File::mkdirs() const{
		if(exists()) return isDirectory();
		std::string dirPath=path.tostring();
		mode_t mode=0755;
		u_index pos=0;
		do{
			pos=dirPath.find('/', pos + 1);
			std::string subDir=dirPath.substr(0, pos);
			if(subDir.empty()) continue;
			struct stat info;
			if(stat(subDir.c_str(), &info) != 0){
				if(mkdir(subDir.c_str(), mode) != 0 && errno != EEXIST){
					return false;
				}
			} else if(!S_ISDIR(info.st_mode)){
				return false;
			}
		} while(pos != std::string::npos);
		return (mkdir(dirPath.c_str(), mode) == 0 || errno == EEXIST);
	}
}
#endif // POSIX